package com.eystar.ext.plugin.crate.db;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.eystar.ext.plugin.tablebind.TableBind;
import com.jfinal.plugin.activerecord.Record;

public class CrateExt<M> extends Record {
	private static final long serialVersionUID = 1L;
	private Class<? extends CrateExt<M>> clazz;
	private String deleteFlag = "delete_flag";
	@SuppressWarnings("rawtypes")
	public static Map<Class<? extends CrateExt>, String> tableMap = new HashMap<>();

	@SuppressWarnings("unchecked")
	public CrateExt() {
		Type genericSuperclass = getClass().getGenericSuperclass();
		clazz = (Class<? extends CrateExt<M>>) ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
	}

	/**
	 * 按某一列查找某一个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public Record findById(Object id) {
		return findFirstByColumn("id",id);
	}
	
	/**
	 * 按某一列查找某一个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public Record findFirstByColumn(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		List<Record> result = findByColumns(map, true, false);
		return result.size() > 0 ? result.get(0) : null;
	}
	
	/**
	 * 按某一列查找某一个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public Record findFirstByColumns(Map<String, Object> columns) {
		List<Record> result = findByColumns(columns, true, false);
		return result.size() > 0 ? result.get(0) : null;
	}
	
	/**
	 * 按某一列查找某一个delete_flag != 1的对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public Record findFirstByColumnSecurity(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		List<Record> result = findByColumns(map, true, true);
		return result.size() > 0 ? result.get(0) : null;
	}
	
	/**
	 * 按某一列查找某一个delete_flag != 1的对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public Record findFirstByColumnsSecurity(Map<String, Object> columns) {
		List<Record> result = findByColumns(columns, true, true);
		return result.size() > 0 ? result.get(0) : null;
	}

	/**
	 * 按某一列查找某几个对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public List<Record> findByColumn(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		return findByColumns(map, false, false);
	}

	/**
	 * 按某一列查找某几个delete_flag != 1的对象
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public List<Record> findByColumnSecurity(String column, Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put(column, value);
		return findByColumns(map, false, true);
	}
	
	/**
	 * 按某几列查找某几个对象
	 * 
	 * @param columns
	 * @param values
	 * @return
	 */
	public List<Record> findByColumns(Map<String, Object> columns) {
		return findByColumns(columns, false, false);
	}

	/**
	 * 按某几列查找某几个delete_flag != 1的对象
	 * 
	 * @param columns
	 * @param values
	 * @return
	 */
	public List<Record> findByColumnsSecurity(Map<String, Object> columns) {
		return findByColumns(columns, false, true);
	}
	
	private List<Record> findByColumns(Map<String, Object> columns, boolean isFirst, boolean deletePseudo) {
		String sql = "select * from " + tableName() + " where 1 = 1";
		for (String column : columns.keySet()) {
			sql += " and " + column + " = ?";
		}
		if (deletePseudo) {
			sql += " and " + deleteFlag + " <> 1";
		}
		if (isFirst) {
			sql += " limit 1";
		}
		
		return CrateDb.find(sql, columns.values().toArray());
	}

	/**
	 * 按一列物理删除记录
	 * 
	 * @param column
	 * @param value
	 * @return
	 */
	public int deleteByColumn(String column, Object value) {
		Map<String, Object> columns = new HashMap<String, Object>();
		columns.put(column, value);
		return deleteByColumns(columns);
	}
	
	/**
	 * 按ID集合物理删除记录
	 * 
	 * @param ids，格式为 1,2,3
	 * @return
	 */
	public int deleteByIds(String ids) {
		String sql = "delete from " + tableName() + " where id in ('" + ids.replace(",", "','") + "')";
		return CrateDb.update(sql);
	}
	/**
	 * 按ID物理删除记录
	 * @param id 
	 * @return
	 */
	public int deleteById(String id) {
		String sql = "delete from " + tableName() + " where id=?";
		return CrateDb.update(sql, id);
	}
	
	/**
	 * 按多列物理删除记录。
	 * 
	 * @param ids
	 * @return
	 */
	private int deleteByColumns(Map<String, Object> columns) {
		String sql = "";
		String tableName = tableName();
		sql += "delete from " + tableName;
		sql += " where 1=1";
		for (String column : columns.keySet()) {
			sql += " and " + column + " = ?";
		}
		return CrateDb.update(sql, columns.values().toArray());
	}

	public String tableName(){
		String tableName = tableMap.get(clazz);
		if(tableName == null) {
			TableBind tb = (TableBind) clazz.getAnnotation(TableBind.class);
			tableName = tb.tableName();
			tableMap.put(clazz, tableName);
		}
		return tableName;
	}
	/**
	 * 批量执行sql
	 * @param recordlist
	 * @param batchSize
	 */
	public void batch(List<String> sqlList, int batchSize){
		CrateDb.batch(sqlList, batchSize);
	}
	/**
	 * 批量保存，报错终止执行
	 * @param recordlist
	 * @param batchSize
	 */
	public void batchSave(List<Record> recordlist, int batchSize){
		CrateDb.batchSave(tableName(), recordlist, batchSize);
	}
	/**
	 * 批量保存，报错跳过继续执行
	 * @param recordlist
	 * @param batchSize
	 */
	public void batchSavePassError(List<Record> recordlist, int batchSize){
		CrateDb.batchSavePassError(tableName(), recordlist, batchSize);
	}
	
	public void save(Record model){
		CrateDb.save(tableName(), model);
	}
	
	public void update(String sql, Object... paras){
		CrateDb.update(sql, paras);
	}
	public void update(Record model){
		CrateDb.update(tableName(), model);
	}
	public List<Record> find(){
		return CrateDb.find("select * from "+tableName());
	}
	public List<Record> find(String sql){
		return CrateDb.find(sql);
	}
	public List<Record> find(String sql, Object... paras) {
		return CrateDb.find(sql, paras);
	}
}
